import java.lang.reflect.Method;

public class AccessPersonMethods {
    public static void main(String[] args) {
        try {
            // 通过反射加载 Person 类
            Class cls = Class.forName("entity.Person");

            // 根据方法名和参数列表获取 static final int getAge()方法
            // 没有参数可以不写或者用 null 表示
            Method getAge = cls.getDeclaredMethod("getAge", null);
            // getAge 方法为 default(package),这里已经超出其访问范围，不能直接访问
            // 通过 setAccessible方法，设定为可以访问
            getAge.setAccessible(true);
            // 调用 getAge方法并传参，没有参数可以不写或者用 null表示
            // getAge方法为静态方法，调用时可以不指定具体Person实例
            Object returnAge = getAge.invoke(null, null);
            System.out.println("年龄是：" + returnAge);

            Object person = cls.newInstance();  // 创建 Person实例

            // 根据方法名和参数列表获取 private void slientMethod()方法
            // 没有参数可以不写或用 null 表示
            Method slientMethod = cls.getDeclaredMethod("silentMethod");
            // slientMethod方法为 private, 这里已经 超出访问范围，不能直接访问
            slientMethod.setAccessible(true);
            // 调用 slientMethod方法并传参，没有参数可以不写活用null表示
            slientMethod.invoke(person, null);

            // 根据方法名和参数列表获取 public void setName(String)方法
            Method setName = cls.getDeclaredMethod("setName", String.class);
            // setName 方法为 public,这里可以直接访问
            // 调用 setName方法并传参
            setName.invoke(person, "New Person");
            // 验证一下结果，调用 public String getName()方法得到 name的值
            Object returnName = cls.getDeclaredMethod("getName").invoke(person,null);
            System.out.println("刚才设定的 name 是: " + returnName );
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
